package com.slipper.codeless.controller;

import com.slipper.codeless.token.TokenManager;
import com.slipper.constants.Constants;
import com.slipper.groovy.service.GroovyService;
import com.slipper.groovy.vo.Message;
import com.slipper.system.codeless.bo.InterfaceBO;
import com.slipper.system.codeless.bo.InterfaceTokenBO;
import com.slipper.system.codeless.service.InterfaceService;
import com.slipper.system.codeless.service.InterfaceTokenService;
import com.slipper.util.ResultUtil;
import com.slipper.util.Tool;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;

import java.util.*;

@RestController
@RequestMapping("/v1")
public class ExternalApiController {
    @Resource
    private InterfaceService interfaceService;
    @Resource
    private InterfaceTokenService interfaceTokenService;
    @Resource
    private TokenManager tokenManager;

    /**
     * 接口调用
     * @param bo 令牌令牌
     */
    @PostMapping("/token")
    public String token(@RequestBody InterfaceTokenBO bo) {
        if (Tool.isBlank(bo.getAppKey())) {
            return ResultUtil.failureResult("appKey不能为空！");
        }
        if (Tool.isBlank(bo.getAppSecret())) {
            return ResultUtil.failureResult("appSecret不能为空！");
        }

        InterfaceTokenBO interfaceToken = interfaceTokenService.queryToken(bo.getAppKey(), bo.getAppSecret());
        if (interfaceToken == null) {
            return ResultUtil.failureResult("appKey或appSecret不正确！");
        }

        InterfaceTokenBO token = tokenManager.createToken(interfaceToken.getTokenTime());
        Map<String, Object> data = new HashMap<>();
        data.put("token", token.getToken());
        data.put("expires_in", token.getTokenTime());
        return ResultUtil.successResult("token获取成功。", data);
    }

    /**
     * 接口开放地址，配置所有以v1开头的地址
     */
    @RequestMapping("/**")
    public String patternAll(HttpServletRequest request, @RequestBody(required = false) Map<String, Object> body) {
        final String mapping = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        final String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        String path = new AntPathMatcher().extractPathWithinPattern(pattern, mapping);

        if (Tool.isBlank(path)) return ResultUtil.failureResult("接口地址不存在！");

        InterfaceBO interfaceBO = interfaceService.queryByPath("/" + path);
        if (interfaceBO == null) return ResultUtil.failureResult("接口地址不存在！");
        if (Constants.YES.equals(interfaceBO.getIfAuth()) && !this.checkToken(request)) {
            return ResultUtil.failureResult("token无效！");
        }

        if (Tool.isBlank(interfaceBO.getGroovyId())) return ResultUtil.failureResult("接口正在开始中...");

        Map<String, String> header = new HashMap<>();
        Enumeration<String> headers = request.getHeaderNames();
        while (headers.hasMoreElements()) {
            String headerName = headers.nextElement();
            header.put(headerName, request.getHeader(headerName));
        }

        Map<String, String> parameter = new HashMap<>();
        Enumeration<String> parameters = request.getParameterNames();
        while (parameters.hasMoreElements()) {
            String parameterName = parameters.nextElement();
            parameter.put(parameterName, request.getParameter(parameterName));
        }

        Map<String, Object> data = new HashMap<>();
        data.put("header", header);
        data.put("parameter", parameter);
        data.put("body", body);
        Object result = GroovyService.runById(interfaceBO.getGroovyId(), data);
        if (result instanceof Message message) {
            if (message.isSuccess()) {
                return ResultUtil.successResult(message.getMessage(), false);
            } else {
                return ResultUtil.failureResult(message.getCode(), message.getMessage());
            }
        }
        return ResultUtil.successResult("执行成功。", result);
    }

    private boolean checkToken(HttpServletRequest request) {
        String auto = request.getHeader("Authorization");
        if (Tool.isBlank(auto)) return false;

        String prefix = "Bearer ";
        String token = auto.length() > prefix.length() ? auto.substring(prefix.length()) : null;
        if (Tool.isBlank(token)) return false;

        return tokenManager.validateToken(token);
    }
}